import ash from '@ash.ts/ash';
import { GameConfig } from '../data/GameConfig';
import { MovementNode } from '../data/nodes';

export class MovementSystem extends ash.ListIteratingSystem<MovementNode> {
    private readonly config: GameConfig;

    public constructor(config: GameConfig) {
        super(MovementNode);
        this.config = config;
    }

    public updateNode(node: MovementNode, time: number): void {
        const { position, motion } = node;
        const { width, height } = this.config;
        const halfW = width / 2;
        const halfH = height / 2;
        position.x += motion.velocityX * time;
        position.y += motion.velocityY * time;
        if (position.x < -halfW) {
            position.x += width;
        }
        if (position.x > halfW) {
            position.x -= width;
        }
        if (position.y < -halfH) {
            position.y += height;
        }
        if (position.y > halfH) {
            position.y -= height;
        }
        position.rotation += motion.angularVelocity * time;
        if (motion.damping > 0) {
            const xDamp: number = Math.abs(Math.cos(position.rotation) * motion.damping * time);
            const yDamp: number = Math.abs(Math.sin(position.rotation) * motion.damping * time);
            if (motion.velocityX > xDamp) {
                motion.velocityX -= xDamp;
            } else if (motion.velocityX < -xDamp) {
                motion.velocityX += xDamp;
            } else {
                motion.velocityX = 0;
            }
            if (motion.velocityY > yDamp) {
                motion.velocityY -= yDamp;
            } else if (motion.velocityY < -yDamp) {
                motion.velocityY += yDamp;
            } else {
                motion.velocityY = 0;
            }
        }
    }
}
